#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys
import time
import json
import random
import logging
import argparse
import subprocess
import threading
from datetime import datetime
from pathlib import Path
from tempmail_auto import TempMailManager, load_proxies_from_env

# 导入项目中的模块
current_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(current_dir)
from logo import print_logo


def setup_logging():
    """配置日志"""
    log_dir = os.path.join(current_dir, "logs")
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    
    log_file = os.path.join(log_dir, f"auto_register_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log")
    
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(levelname)s: %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
        handlers=[
            logging.FileHandler(log_file, encoding="utf-8"),
            logging.StreamHandler()
        ]
    )
    return log_file


def run_cursor_registration(timeout=600):
    """
    运行Cursor注册程序
    
    参数:
        timeout: 注册超时时间（秒）
        
    返回:
        dict: 包含注册结果的字典
    """
    try:
        # 使用subprocess运行cursor_pro_keep_alive.py
        cursor_script = os.path.join(current_dir, "cursor_pro_keep_alive.py")
        
        logging.info("开始运行Cursor注册程序")
        registration_process = subprocess.Popen(
            [sys.executable, cursor_script],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            encoding="utf-8"
        )
        
        # 创建超时监控线程
        timer = threading.Timer(timeout, lambda: registration_process.kill())
        
        try:
            timer.start()
            
            # 等待语言选择提示
            time.sleep(2)
            
            # 选择中文(1)
            registration_process.stdin.write("1\n")
            registration_process.stdin.flush()
            
            # 等待操作选择提示
            time.sleep(2)
            
            # 选择完成注册(2)
            registration_process.stdin.write("2\n")
            registration_process.stdin.flush()
            
            # 等待程序完成
            stdout, stderr = registration_process.communicate()
            
            if registration_process.returncode != 0:
                logging.error(f"Cursor注册程序执行失败: {stderr[:200]}...")
                return {"success": False, "error": "程序异常退出", "details": stderr[:500]}
            
            # 提取账号信息
            email = extract_email_from_output(stdout)
            password = extract_password_from_output(stdout)
            
            # 检查是否成功注册
            if "所有操作已完成" in stdout or "All operations completed" in stdout:
                logging.info("Cursor账号注册成功")
                result = {
                    "success": True, 
                    "email": email, 
                    "password": password
                }
                
                # 提取token信息
                token = extract_token_from_output(stdout)
                if token:
                    result["token"] = token
                
                return result
            else:
                logging.warning("未检测到注册成功信息，可能注册失败")
                return {
                    "success": False, 
                    "error": "未检测到成功信息", 
                    "email": email, 
                    "password": password
                }
            
        finally:
            timer.cancel()
            
            # 确保进程已终止
            if registration_process.poll() is None:
                logging.warning("注册进程未自动终止，强制结束")
                registration_process.kill()
        
    except Exception as e:
        logging.error(f"执行Cursor注册程序时出错: {str(e)}")
        return {"success": False, "error": str(e)}


def extract_email_from_output(output):
    """从输出中提取邮箱地址"""
    import re
    match = re.search(r"邮箱: ([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})", output)
    if match:
        return match.group(1)
    
    # 匹配英文提示
    match = re.search(r"email: ([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})", output)
    if match:
        return match.group(1)
    
    return None


def extract_password_from_output(output):
    """从输出中提取密码"""
    import re
    match = re.search(r"密码: ([a-zA-Z0-9!@#$%^&*]+)", output)
    if match:
        return match.group(1)
    
    # 匹配英文提示
    match = re.search(r"password: ([a-zA-Z0-9!@#$%^&*]+)", output)
    if match:
        return match.group(1)
    
    return None


def extract_token_from_output(output):
    """从输出中提取token"""
    import re
    match = re.search(r"token: ([a-zA-Z0-9._-]+)", output)
    if match:
        return match.group(1)
    
    return None


def save_account_info(accounts, filename="cursor_accounts.json"):
    """保存账号信息到JSON文件"""
    file_path = os.path.join(current_dir, filename)
    
    # 读取现有账号
    existing_accounts = []
    if os.path.exists(file_path):
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                existing_accounts = json.load(f)
        except Exception as e:
            logging.error(f"读取账号文件出错: {str(e)}")
    
    # 合并账号列表
    all_accounts = existing_accounts + accounts
    
    # 去重（基于邮箱）
    unique_accounts = []
    seen_emails = set()
    for account in all_accounts:
        email = account.get("email")
        if email and email not in seen_emails:
            seen_emails.add(email)
            unique_accounts.append(account)
    
    # 保存到文件
    try:
        with open(file_path, "w", encoding="utf-8") as f:
            json.dump(unique_accounts, f, indent=2, ensure_ascii=False)
        logging.info(f"已保存 {len(accounts)} 个新账号信息到 {filename}")
        return True
    except Exception as e:
        logging.error(f"保存账号信息时出错: {str(e)}")
        return False


def auto_register(count, interval, timeout=600, retry_on_failure=True, max_retries=3):
    """
    自动循环注册Cursor账号
    
    参数:
        count: 注册账号数量
        interval: 每次注册间隔（秒）
        timeout: 单次注册超时时间（秒）
        retry_on_failure: 失败时是否重试
        max_retries: 最大重试次数
    """
    success_count = 0
    failed_count = 0
    account_list = []
    
    # 加载代理设置
    proxies = load_proxies_from_env()
    temp_mail_manager = TempMailManager(proxies=proxies)
    
    for i in range(1, count + 1):
        logging.info(f"===== 开始第 {i}/{count} 次注册 =====")
        
        # 当前尝试次数
        current_attempt = 1
        
        while current_attempt <= max_retries:
            # 创建新的临时邮箱
            logging.info(f"创建新的临时邮箱 (尝试 {current_attempt}/{max_retries})")
            mailbox = temp_mail_manager.create_new_mailbox()
            
            if not mailbox:
                logging.error("创建临时邮箱失败")
                if retry_on_failure and current_attempt < max_retries:
                    current_attempt += 1
                    logging.info(f"将在 10 秒后重试...")
                    time.sleep(10)
                    continue
                else:
                    failed_count += 1
                    logging.error("跳过本次注册")
                    break
            
            # 更新.env文件
            logging.info(f"使用临时邮箱: {mailbox['email']}")
            if not temp_mail_manager.update_env_file(mailbox):
                logging.error("更新.env文件失败")
                if retry_on_failure and current_attempt < max_retries:
                    current_attempt += 1
                    logging.info(f"将在 5 秒后重试...")
                    time.sleep(5)
                    continue
                else:
                    failed_count += 1
                    logging.error("跳过本次注册")
                    break
            
            # 运行注册程序
            registration_result = run_cursor_registration(timeout)
            
            if registration_result.get("success"):
                success_count += 1
                logging.info(f"第 {i} 次注册成功！当前成功率: {success_count}/{i}")
                
                # 添加时间戳和源邮箱信息
                registration_result["timestamp"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                registration_result["temp_email"] = mailbox["email"]
                
                # 添加到账号列表
                account_list.append(registration_result)
                
                # 保存当前账号信息
                save_account_info([registration_result])
                
                break  # 成功，跳出重试循环
            else:
                logging.error(f"注册失败: {registration_result.get('error', '未知错误')}")
                
                # 检查是否应该重试
                if retry_on_failure and current_attempt < max_retries:
                    current_attempt += 1
                    logging.info(f"将在 30 秒后重试...")
                    time.sleep(30)
                    continue
                else:
                    failed_count += 1
                    logging.error(f"第 {i} 次注册失败。当前成功率: {success_count}/{i}")
                    
                    # 如果有邮箱和密码信息，仍然保存
                    if registration_result.get("email") and registration_result.get("password"):
                        registration_result["timestamp"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                        registration_result["temp_email"] = mailbox["email"]
                        registration_result["status"] = "FAILED"
                        account_list.append(registration_result)
                    
                    break  # 放弃当前注册
        
        # 如果不是最后一次，则等待指定的间隔时间
        if i < count:
            # 根据成功/失败采用不同的等待策略
            if registration_result.get("success"):
                # 成功注册后使用标准间隔
                actual_interval = random.uniform(interval * 0.8, interval * 1.2)  # 随机化间隔
            else:
                # 失败注册后使用更长的间隔
                actual_interval = random.uniform(interval * 1.2, interval * 1.5)
                
            logging.info(f"等待 {actual_interval:.1f} 秒后进行下一次注册...")
            time.sleep(actual_interval)
    
    # 保存所有账号信息
    if account_list:
        save_account_info(account_list)
    
    # 总结
    logging.info(f"===== 自动注册完成 =====")
    logging.info(f"总计尝试: {count} 次")
    logging.info(f"成功注册: {success_count} 次")
    logging.info(f"失败注册: {failed_count} 次")
    if count > 0:
        logging.info(f"成功率: {(success_count/count)*100:.1f}%")
    
    return {"total": count, "success": success_count, "failed": failed_count, "accounts": account_list}


if __name__ == "__main__":
    # 解析命令行参数
    parser = argparse.ArgumentParser(description="Cursor账号自动批量注册工具")
    parser.add_argument("-c", "--count", type=int, default=5, help="要注册的账号数量（默认: 5）")
    parser.add_argument("-i", "--interval", type=float, default=300, help="注册间隔时间（秒）（默认: 300）")
    parser.add_argument("-t", "--timeout", type=int, default=600, help="单次注册超时时间（秒）（默认: 600）")
    parser.add_argument("--no-retry", action="store_true", help="失败时不重试")
    parser.add_argument("-r", "--retries", type=int, default=3, help="最大重试次数（默认: 3）")
    parser.add_argument("-o", "--output", type=str, default="cursor_accounts.json", help="账号信息输出文件（默认: cursor_accounts.json）")
    parser.add_argument("--manual", action="store_true", help="使用手动模式获取临时邮箱")
    args = parser.parse_args()
    
    log_file = setup_logging()
    print_logo()
    
    print("\n===== Cursor账号自动批量注册工具 =====")
    print(f"计划注册账号数量: {args.count}")
    print(f"注册间隔时间: {args.interval} 秒")
    print(f"单次注册超时: {args.timeout} 秒")
    print(f"失败时重试: {'否' if args.no_retry else '是'}")
    if not args.no_retry:
        print(f"最大重试次数: {args.retries}")
    print(f"账号保存位置: {args.output}")
    print(f"日志文件: {os.path.basename(log_file)}")
    print(f"邮箱模式: {'手动' if args.manual else '自动'}")
    print("==================================")
    
    # 检查网络连接状况
    try:
        import socket
        socket.gethostbyname("tempmail.plus")
        print("✅ 网络连接正常")
    except Exception:
        print("⚠️ 网络连接可能存在问题，建议使用--manual手动模式")
        # 如果检测到网络问题且没有指定手动模式，提示用户
        if not args.manual:
            print("\n提示: 检测到可能存在网络问题，建议:")
            print("1. 配置代理: 在.env中设置HTTP_PROXY和HTTPS_PROXY")
            print("2. 或使用手动模式: python auto_register.py --manual\n")
    
    confirm = input("是否开始自动注册? (y/n): ")
    if confirm.lower() == 'y':
        # 获取邮箱
        proxies = load_proxies_from_env()
        temp_mail_manager = TempMailManager(proxies=proxies)
        
        # 如果使用手动模式，先获取邮箱信息
        if args.manual:
            print("\n请先手动获取临时邮箱信息...")
            manual_mailbox = temp_mail_manager._create_manual_mailbox()
            if manual_mailbox and temp_mail_manager.update_env_file(manual_mailbox):
                print("✅ 已成功设置手动邮箱")
            else:
                print("❌ 手动邮箱设置失败，程序终止")
                sys.exit(1)
        
        result = auto_register(
            args.count, 
            args.interval, 
            timeout=args.timeout,
            retry_on_failure=not args.no_retry,
            max_retries=args.retries
        )
        
        # 显示最终结果
        if result["success"] > 0:
            print(f"\n成功注册了 {result['success']} 个账号!")
            print(f"账号信息已保存到 {args.output}")
        else:
            print("\n未能成功注册任何账号，请检查日志文件查找原因")
    else:
        print("已取消操作") 